<script setup>
import {ref} from 'vue'

const rankList = [
  {label: "简单", tr: 9, td: 9, mineNum: 10},
  {label: "中等", tr: 16, td: 16, mineNum: 40},
  {label: "困难", tr: 16, td: 30, mineNum: 99}
]
const rankIndex = ref(0)
const squares = ref([])

function init() {
  squares.value = []
  let {tr, td, mineNum} = rankList[rankIndex.value]
  for (let i = 0; i < tr; i++) {
    squares.value[i] = []
    for (let j = 0; j < td; j++) {
      squares.value[i][j] = {
        x: i,
        y: j,
        isMine: false,
        isOpen: false,
        isFlag: false,
        nearMine: 0
      }
    }
  }

  const positions = new Set();
  for (let i = 0; i < mineNum; i++) {
    let x, y;
    do {
      x = Math.floor(Math.random() * tr);
      y = Math.floor(Math.random() * td);
    } while (positions.has(`${x},${y}`));
    positions.add(`${x},${y}`);
    squares.value[x][y].isMine = true;
  }

  for (let i = 0; i < tr; i++) {
    for (let j = 0; j < td; j++) {
      let nearMine = 0
      for (let x = i - 1; x <= i + 1; x++) {
        for (let y = j - 1; y <= j + 1; y++) {
          if (x >= 0 && x < tr && y >= 0 && y < td && squares.value[x][y].isMine) {
            nearMine++
          }
        }
      }
      squares.value[i][j].nearMine = nearMine
    }
  }
}

function onClick(item) {
  let {tr, td} = rankList[rankIndex.value]
  if (item.isFlag) {
    return
  }
  squares.value[item.x][item.y].isOpen = true
  if (item.isMine) {
    for (let i = 0; i < tr; i++) {
      for (let j = 0; j < td; j++) {
        squares.value[i][j].isOpen = true
      }
    }
    alert('Game Over')
  } else if (item.nearMine === 0) {
    openNear(item)
  }
}

function openNear(item) {
  let {tr, td} = rankList[rankIndex.value]
  for (let x = item.x - 1; x <= item.x + 1; x++) {
    for (let y = item.y - 1; y <= item.y + 1; y++) {
      if (x >= 0 && x < tr && y >= 0 && y < td && !squares.value[x][y].isOpen && !squares.value[x][y].isFlag) {
        squares.value[x][y].isOpen = true
        if (squares.value[x][y].nearMine === 0) {
          openNear(squares.value[x][y])
        }
      }
    }
  }
}

function checkWin() {
  let win = true
  let {tr, td} = rankList[rankIndex.value]
  for (let i = 0; i < tr; i++) {
    for (let j = 0; j < td; j++) {
      if (squares.value[i][j].isFlag && !squares.value[i][j].isMine) {
        win = false
        break
      }
    }
  }
  return win
}

let flagNumber = 0

function onClickRight(item) {
  if(item.isOpen){
    return
  }
  let {mineNum} = rankList[rankIndex.value]
  item.isFlag = !item.isFlag
  if (item.isFlag) {
    flagNumber++
    if (flagNumber === mineNum) {
      let res = checkWin()
      if (res) {
        alert('You Win')
      }
    }
  } else {
    flagNumber--
  }
}

init()
</script>

<template>
  <div class="outer">
    <div>
      <div class="header">
        <el-select v-model="rankIndex">
          <el-option v-for="(item,index) in rankList" :key="index" :label="item.label" :value="index"></el-option>
        </el-select>
        <el-button @click="init" class="button" type="primary">重新开始</el-button>
      </div>

      <div v-for="square in squares" :key="square.x" class="outerBox">
        <div v-for="item in square" :key="item.y" class="square" :class="item.isOpen ? 'square-open':''"
             @click="onClick(item)" @click.right.prevent="onClickRight(item)">
          <div v-if="item.isFlag">🚩</div>
          <div v-else>
            <span v-if="item.isOpen && item.isMine">💣</span>
            <span v-else-if="item.isOpen && item.nearMine>0">{{ item.nearMine }}</span>
            <span v-else></span>
          </div>
        </div>
      </div>
    </div>

  </div>

</template>

<style scoped>
.outer {
  margin: 0;
  display: flex;
  place-items: center;
  justify-content: center;
}

.header {
  display: flex;
  gap: 20px;
  align-items: center;
  margin-bottom: 20px;
}

.outerBox {
  display: flex;
}

.square {
  width: 30px;
  height: 30px;
  line-height: 30px;
  border: 1px solid #000;
  cursor: pointer;
  background: #888888;
  text-align: center;
}

.square-open {
  background: #ccc;
}

.square:hover {
  background: #fff;
}
</style>
